package com.smartplatform.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.smartplatform.cache.CategoriesCache;
import com.smartplatform.constants.ResultCode;
import com.smartplatform.event.CategoryChangeEvent;
import com.smartplatform.exception.AddDateException;
import com.smartplatform.exception.DeleteDataException;
import com.smartplatform.mapper.SysCategoryMapper;
import com.smartplatform.pojo.CheckType;
import com.smartplatform.pojo.MyBaseUser;
import com.smartplatform.pojo.SysCategory;
import com.smartplatform.service.SysCategoryService;
import com.smartplatform.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author 咕唧
 * @Date 2022/5/30 15:45
 * @Version 1.0
 */
@Service
@Transactional
public class SysCategoryServiceImpl implements SysCategoryService {
    private SysCategoryMapper sysCategoryMapper;

    private ApplicationContext context;

    private CategoriesCache categoriesCache;

    @Autowired
    public void setCategoriesCache(CategoriesCache categoriesCache) {
        this.categoriesCache = categoriesCache;
    }

    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    @Autowired
    public void setSysCategoryMapper(SysCategoryMapper sysCategoryMapper) {
        this.sysCategoryMapper = sysCategoryMapper;
    }

    @Override
    public void addCategory(SysCategory sysCategory) {
        //数据校验
        Assert.isTrue(!sysCategory.isEmpty(CheckType.ADD), () -> {
            throw new AddDateException("必要数据为空", ResultCode.DATA_NULL);
        });
        //在session中获取保存的用户信息
        //使用拦截器拦截地址，保证用户登录之后才能进行访问
        MyBaseUser userInfo = SecurityUtils.getUserInfo(false);
        sysCategory.setCreateBy(userInfo.getUsername());
        sysCategory.setCreateTime(new Date());
        sysCategoryMapper.addSysCategory(sysCategory);
        //设置监听事件，当数据库内容发生改变时，重新加载缓存
        context.publishEvent(new CategoryChangeEvent());
    }

    @Override
    public PageInfo<SysCategory> findAll(int pageSize, int pageNum) {
        //数据校验
        if (pageSize < 1) {
            pageSize = 10;
        }
        if (pageNum < 1) {
            pageNum = 1;
        }
        //设置缓存，用户启动时查询数据库，把返回结果放在内存中，提升用户访问效率
        //TODO
        List<SysCategory> categoryList = categoriesCache.getCategoryList(true);
        //开启分页
        PageHelper.startPage(pageNum, pageSize);
        List<SysCategory> collect = categoryList.stream()
                .skip((pageNum - 1) * pageSize)//偏移量，跳过的数据
                .limit(pageSize)//需要的数据
                .collect(Collectors.toList());//收集结果
        //保存到pageInfo中
        PageInfo<SysCategory> pageInfo = new PageInfo<>(collect);
        //手动设置分页数据的其他属性
        pageInfo.setTotal(categoryList.size());
        return pageInfo;
    }

    @Override
    public void deleteByCId(Long cId) {
        //数据校验
        Assert.isTrue(cId > 0, () -> {
            throw new DeleteDataException("主键不符合要求", ResultCode.ID_NOT_ALLOWED);
        });
        //获取用户登录数据
        MyBaseUser userInfo = SecurityUtils.getUserInfo(false);
        //删除分类，记录更新时间和删除用户
        //逻辑删除
        sysCategoryMapper.deleteById(cId, new Date(), userInfo.getUsername());
        //通知缓存,数据发生变化
        context.publishEvent(new CategoryChangeEvent());
    }

    @Override
    public void deleteByIds(List<Long> ids, Long status) {
        Assert.notEmpty(ids, () -> {
            throw new DeleteDataException("主键不符合要求", ResultCode.ID_NOT_ALLOWED);
        });
        //获取的当前登录的用户的数据
        MyBaseUser sysUserInfo = SecurityUtils.getUserInfo(false);
        for (Long id : ids) {
            System.out.println(id);
        }
        sysCategoryMapper.deleteByIds(ids, new Date(), sysUserInfo.getUsername(), status);
        //通知缓存,数据发生变化
        context.publishEvent(new CategoryChangeEvent());
    }

    @Override
    public PageInfo<SysCategory> findByNameOrStatus(String categoryName, int status) {
        //取出所有数据
        List<SysCategory> categoryList = categoriesCache.getCategoryList(true);
        //开启分页
        int pageSize = 10;
        int pageNum = 1;
        //开启分页
        PageHelper.startPage(pageNum, pageSize);

        List<SysCategory> collect = new ArrayList<>();
        if (categoryName != null && categoryName.trim().length() > 0) {
            List<SysCategory> collectName = categoryList.stream()
                    .filter(sysCategory -> sysCategory.getCategoryName().contains(categoryName))
                    .collect(Collectors.toList());//收集结果
            collect.addAll(collectName);
        }

        if (status >= 0) {
            List<SysCategory> collectStatus = categoryList.stream()
                    .filter(sysCategory -> sysCategory.getStatus().equals(Long.valueOf(status)))
                    .collect(Collectors.toList());//收集结果
            collect.addAll(collectStatus);
        }
        collect = collect.stream()
                .skip((pageNum - 1) * pageSize)//偏移量，跳过的数据
                .limit(pageSize)//需要的数据
                .collect(Collectors.toList());//收集结果
        //保存到pageInfo中
        PageInfo<SysCategory> pageInfo = new PageInfo<>(collect);
        //手动设置分页数据的其他属性
        pageInfo.setTotal(categoryList.size());
        return pageInfo;
    }
}
